var htData = {
  fragments : null,
  /*
  fragments = Array(fragment);
  fragment = {
            startPos,
            endPos,
            content,
            colorIndex,
            viewpoints(array)}
  */
  porps : null,
  /*
  porps = Array(entity);
  entity = {
    name,
    href,
    viewpoints = {name, href},
    topics = {name, href},
    attributes = {name, value},
    resources = {name, href}}*/
  viewpoints : null,
  docHtml : null,
  topics : null
  /*
  { topic.colorIndex,
    topic.topics{name, value}
  }*/
}

//var fragments = null;
//var porps = null;
//var viewpoints = null;

var proxy = {
  currentUri : null,
  parentUri : null,
	defaultService : null,
	user : null,
	pass : null,

	init: function(){
    var pref = new Preferences(PREF_PREFIX);
  	this.defaultService = pref.getPref("service", DEFAULT_SERVICE);
  	this.user = pref.getPref("username", DEFAULT_HT_USER);
  	this.pass = pref.getPref("password", DEFAULT_HT_PASS);
  },

  setUri: function(uri){
    this.currentUri = uri;
    if(this.currentUri.indexOf("#") > 0)
      this.parentUri = this.currentUri.substring(0,this.currentUri.indexOf("#"));
    else
      this.parentUri = this.currentUri;
  },

  getViewpoints : function(){
    var viewpointsObject = new Viewpoints();
  	viewpointsObject.uri = this.defaultService + "viewpoint/";
  	debug("[proxy.js::getViewpoints] viewpoints uri:" + viewpointsObject.uri, 4);
  	viewpointsObject = viewpointsObject.httpGet();
  	if(viewpointsObject != null)
  	  htData.viewpoints = viewpointsObject.viewpoints;
  	//debug("[proxy.js::getViewpoints] viewpoints number:" + viewpoints.length,4);
  },

  getPorps : function(){
    htData.porps = new Array();
    var requestUrl = this.defaultService + "resource/" + encodeURIComponent(this.currentUri);
    var resource = new Resource();
    resource.uri = requestUrl;
    resource.href = this.currentUri;
    var resource = resource.httpGet();
    if(resource == null)
      return false;
    for (var i = 0; i < resource.entities.length; i++){
      var tmpEntity = {};
      tmpEntity.name = resource.entities[i].name;
      tmpEntity.href = resource.entities[i].href;

      var entity = new Entity();
      entity.uri = resource.entities[i].href;
      entity = entity.httpGet();
      if(entity == null) return false;

      tmpEntity.resources = entity.resources;
      tmpEntity.attributes = entity.attributes;
      var viewpointList = new Array();
      for( var j = 0; j < entity.topics.length; j++){
        var href = entity.topics[j].href;
        //debug("[proxy.js::getPorps] topics:" + href, 1);
        if(href != "")
          href = href.substr(0, href.indexOf("/topic/")+1);
        viewpointList.push(href);
      }
      //debug("[proxy.js::getPorps] viewpointList:" + dump(viewpointList), 1);
      viewpointList = viewpointList.unique(true);
      //debug("[proxy.js::getPorps] viewpointList:" + dump(viewpointList), 1);
      var vps = new Array();
      for( var j = 0; j < viewpointList.length; j++){
        var tmpViewpoint = {};
        tmpViewpoint.href = viewpointList[j];
        for( var k = 0; k < htData.viewpoints.length; k++)
          if(htData.viewpoints[k].href == tmpViewpoint.href)
            tmpViewpoint.name = htData.viewpoints[k].name;
        vps.push(tmpViewpoint);
      }
      tmpEntity.viewpoints = vps;

      htData.porps.push(tmpEntity);
    }
  },

  getFragments : function(){
    htData.fragments = new Array();
    if(this.currentUri == "")
      return false;

    var requestUri = this.defaultService + "entity/" + encodeURIComponent(this.parentUri) + "/";

    var entity = new Entity();
    entity.uri = requestUri;
    entity = entity.httpGet();
    if(entity == null)
      return false;

    var regex = /\/([0-9]+)\+([0-9]+)\/?$/;
    for(var i = 0;i < entity.relatedEntities.length; i++){
      var tmpFragment = {};
      var uri = entity.relatedEntities[i].href;
      if(!regex.test(uri)) continue;
      var res = uri.match(regex);
      try{
        tmpFragment.startPos = parseInt(res[1]);
        tmpFragment.endPos = parseInt(res[2]);
      } catch(ex) {continue;}
      if(tmpFragment.startPos > tmpFragment.endPos){
  			var temp = tmpFragment.startPos;
  			tmpFragment.startPos = tmpFragment.endPos;
  			tmpFragment.endPos = temp;
  		}

      //get fragment entity detail
      var tmpEntity = new Entity();
      tmpEntity.uri = uri;
      tmpEntity = tmpEntity.httpGet();
      if(tmpEntity == null) continue;

      for(var j = 0; j < tmpEntity.attributes.length; j++){
        var attribute = tmpEntity.attributes[j];
        if(attribute.name=="type" && attribute.value=="fragment")
          tmpFragment.isFragment = true;
        if(attribute.name=="name")
          tmpFragment.content = attribute.value;
        if(attribute.name=="colorIndex"){
          tmpFragment.colorIndex = parseInt(attribute.value);
          if(tmpFragment.colorIndex == "NaN")
            tmpFragment.colorIndex = 0;
        }
      }

      var viewpointList = new Array();
      for( var j = 0; j < tmpEntity.topics.length; j++){
        var href = tmpEntity.topics[j].href;
        if(href != "")
          href = href.substr(0, href.indexOf("/topic/")+1);
        viewpointList.push(href);
      }
      viewpointList = viewpointList.unique(true);
      debug("[proxy.js::getFragments] viewpointList:" + dump(viewpointList), 4);
      tmpFragment.viewpoints = viewpointList;

      if(tmpFragment.isFragment == true)
        htData.fragments.push(tmpFragment);
    }
    htData.fragments.sortNum();
  },

  getColorTopics: function()
  {
    htData.topics = new Array(5);
    for(var i = 0; i < 5; i++){
      var entity = new Entity();
      entity.uri = this.defaultService + COLORENTITY_PREFIX + i + "/";
      entity = entity.httpGet();
      if(entity != null)
        htData.topics[i] = entity.topics;
    }
  },

  removeFragment: function(fragment){
    var iPos = -1;
    for(var i = 0; i < htData.fragments.length; i++){
      var tmpFragment = htData.fragments[i];
      if(tmpFragment.startPos == fragment.startPos && tmpFragment.endPos == fragment.endPos){
        iPos = i;
        break;
      }
    }
    if(iPos == -1) return false;

    var requestUri = this.defaultService + "entity/" + encodeURIComponent(this.parentUri) + "/" + fragment.startPos + "+" + fragment.endPos;
    var entity = new Entity();
    entity.uri = requestUri;
    var res = entity.httpDelete(this.user, this.pass);
    if(res)
      htData.fragments.splice(iPos, 1);
    return res;
  },

  addFragment: function(fragment, viewpointUri){
    debug("[proxy.js::addFragment] fragment:" + dump(fragment), 4);
    debug("[proxy.js::addFragment] viewpointUri:" + viewpointUri, 4);
	  for(var i = 0;i < htData.fragments.length; i++){
			if((fragment.startPos <= htData.fragments[i].startPos && fragment.endPos >= htData.fragments[i].startPos)
				|| (fragment.startPos >= htData.fragments[i].startPos && fragment.endPos <= htData.fragments[i].endPos)
				|| (fragment.startPos <= htData.fragments[i].endPos && fragment.endPos >= htData.fragments[i].endPos))
			{
				alert("You can't add fragment at this selection!");
				return false;
			}
		}

    var colorTopic = this.getColorTopic(fragment.colorIndex, viewpointUri);
    debug("[proxy.js::addFragment] colorTopicUri:" + dump(colorTopic), 4);
		var requestUri = this.defaultService + "entity/" + encodeURIComponent(this.parentUri) + "/" + fragment.startPos + "+" + fragment.endPos;
    var entity = new Entity();
    entity.uri = requestUri;

    entity.addAttribute("name",fragment.content);
		entity.addAttribute("type","fragment");
		entity.addAttribute("colorIndex",fragment.colorIndex);
		entity.addResource("highlight", HIGHLIGHT_PHPSCRIPT + this.parentUri);
		entity.addResource("fragment", HIGHLIGHT_PHPSCRIPT + this.parentUri);
		if(colorTopic != null){
		  entity.addTopic(colorTopic.name, colorTopic.href);
		  fragment.viewpoints = new Array(viewpointUri);
		}
    var res = entity.httpPut(this.user, this.pass);
    if(!res) return false;
    htData.fragments.push(fragment);
    htData.fragments.sortNum();
    return true;
  },

  updateFragment: function(fragment, colorIndex, viewpointUri){
    var requestUri = this.defaultService + "entity/" + encodeURIComponent(this.parentUri) + "/" + fragment.startPos + "+" + fragment.endPos;

    var colorTopic = null;
    var originalColorTopic = null;
    if(viewpointUri != null){
      colorTopic = this.getColorTopic(colorIndex, viewpointUri);
      originalColorTopic = this.getColorTopic(fragment.colorIndex, viewpointUri);
      debug("[proxy.js::updateFragment] colorTopicUri:" + dump(colorTopic), 4);
      debug("[proxy.js::updateFragment] originalColorTopicUri:" + dump(originalColorTopic), 4);
    }

    var entity = new Entity();
    entity.uri = requestUri;
    entity = entity.httpGet();
    if(entity == null) return false;
    entity.uri = requestUri;
    debug("[proxy.js::updateFragment] request URL:" + entity.uri, 4);

    for(var i = 0; i < entity.attributes.length; i++){
      if(entity.attributes[i].name == "colorIndex")
        entity.attributes[i].value = colorIndex;
    }
    if(colorTopic != null){
		  entity.addTopic(colorTopic.name, colorTopic.href);
		  entity.removeTopic(originalColorTopic.href);
		}
    var res = entity.httpPut(this.user, this.pass);
    if(!res) return false;

    for(var i = 0; i < htData.fragments.length; i++){
      var tmpFragment = htData.fragments[i];
      if(tmpFragment.startPos == fragment.startPos && tmpFragment.endPos == fragment.endPos){
        htData.fragments[i].colorIndex = colorIndex;
        break;
      }
    }
    return true;
  },

  getColorTopic: function(colorIndex, viewpointUri){
    debug("[proxy.js::getColorTopic] colorIndex:" + colorIndex + ", viewpointUri:" + viewpointUri, 3);
    var colorTopicUri = null;
    var topic = {};
    var topicName = "Color:" + COLORS[colorIndex];
    topic.name = topicName;

    if(viewpointUri == null) return null;
    debug("[proxy.js::getColorTopic] htData.topics[" + colorIndex + "]:" + dump(htData.topics[colorIndex]), 3);
    var topics = htData.topics[colorIndex];
    if(topics != null)
    	for(var i=0; i < topics.length; i++){
        var topicUri = topics[i].href + "";
        debug("[proxy.js::getColorTopic] topicUri:" + topicUri, 1);
        if(topicUri.startsWith(viewpointUri))
        {
          topic.href = topicUri;
          break;
        }
    	}
  	if(topic.href == null){
  	  var tmpEntity = {};
  	  tmpEntity.name = "colorIndex";
  	  tmpEntity.href = this.defaultService + COLORENTITY_PREFIX + colorIndex + "/";
      debug("[proxy.js::getColorTopic] colorEntity uri:" + tmpEntity.href, 3);
  	  var topic = new Topic();
  	  topic.entities.push(tmpEntity);

      topic.name = topicName;
      topic.viewpoint.href = viewpointUri;

  	  topic.href = topic.httpPost(viewpointUri + "topic/", this.user, this.pass);
  	  if(topic.href == null){
  	    debug("[proxy.js::updateFragment] create color topic failed:" + viewpointUri, 1);
  	    return false;
  	  }
      if (htData.topics[colorIndex] == null)
        htData.topics[colorIndex] = new Array(topic);
      else{
        htData.topics[colorIndex].push(topic);
      }
  	}
  	return topic;
  }
}